$.fn.myAutocomplite = function () {
	Autocomplete.init(this, options);
};

Autocomplete = {
		// serverAnswer - ключ массива, возвращаемого сервером, где будут храниться данные для автокомплита
		autocompleteField : {},		// Объект поля для автокомплита 
		idEssenceField: 0,			// объект hidden-поля для хранения айдишников выбираемых элементов
		essenceIdName : '',			// Имя первичного ключа сущности, для которой выполняется автокомплит
		rightChoose : false,		// Флаг выбранности поля
		timeoutId : 0,				// id последнего таймаута, используемого для задержки отправки запроса на сервер
		lastAnswer : [],			// массив последних данных, полученных от сервера
		lastFieldValue : null,		// значнение поля до очередного нажатия клавиши
		onSelect : null,			// Функция, выполянемая после выбора одного из значений
		requestUrl : '',			// Адрес, на который будут отправляться запросы
		wrongString : '',			// Строка, которая будет вставляться в текстовое поле при неправльном выборе
		isFocused: false,			// Флаг, показывающий в фокусе ил сейчас поле
		
		init: function (field,options) {
			var self = this;
			self.autocompleteField = field;											// Получаем объект поля для автокомплита
			self.essenceIdName = options.essenceId;									// Записываем имя первичного ключа для сущности автокомплита
			self.idEssenceField = $('#' + self.essenceIdName);						// Получаем объект hidden-поля для хранения айдишников выбираемых элементов
			if(self.idEssenceField.val() != '') self.rightChoose = true;				// Если при загрузке страницы существовал id в hidden-поле, то отмечаем флаг выбора
			self.autocompleteField.wrap('<div class="ac-wrapper"></div>');
			self.autocompleteField.after('<div class="suggestion-list"></div>');
			self.autocompleteField.next().css({'width' : (self.autocompleteField.outerWidth() - 2) + 'px'});
			self.onSelect = options.onSelect ? options.onSelect : null;
			self.howShow = options.howShow;
			self.howSelect = options.howSelect ? options.howSelect : options.howShow;
			self.requestUrl = options.requestUrl;
			if(options.wrongString) self.wrongString = options.wrongString;
			self.focusHeandler();
			
			$(".ac-wrapper").on('mouseenter', '.suggestion-item', function(e) {
				$(".suggestion-item.active").removeClass('active');
				$(this).toggleClass('active');
			});
		},
		
		// Активизируется, когда поле вввода в фокусе
		lookForField: function() {
			var self = this;
			self.isFocused = true;
			// Увод фокуса с поля
			self.autocompleteField.bind('blur',function() {
				//console.log('blur');
				if(!self.rightChoose) self.clearField();
				self.stopLookForField();
			});
			// Нажатие кнопок
			self.autocompleteField.bind('keyup',function() {
				//console.log('keyup');
				self.rightChoose = false;
				clearTimeout(self.timeoutId);
				if(self.autocompleteField.val() == '') {
					self.hideSuggestionList();
					self.lastFieldValue = '';
				}
				else if(self.lastFieldValue != self.autocompleteField.val()) self.timeoutId = setTimeout(function() {if(self.autocompleteField.val() != '') self.request(); self.lastFieldValue = self.autocompleteField.val();}, 300);
			});
			
			$('body').bind('mousedown', function(event) {
				//console.log('mousedown');
				var clickedElement = $(event.target) || $(event.srcElement);
				if(clickedElement.hasClass('suggestion-item')) {
					self.selectItem(clickedElement.index());
				}
				else if(!clickedElement.is(self.autocompleteField)) {
					self.autocompleteField.blur();
				}
			});
			
			// Нажатие кнопок
			self.autocompleteField.bind('keydown', function(e) {
				switch (e.keyCode) {
				case 27: // esc
					self.autocompleteField.blur();
					break;
				case 9: // tab
				case 13: // enter
					var activeItem = $('.suggestion-item.active');
					if(activeItem.index() != -1) {
						self.selectItem(activeItem.index())
					}
					break;
				case 38: // key up
					var activeItem = $('.suggestion-item.active');
					if(activeItem.index() != -1 && $('.suggestion-item').eq(activeItem.index() - 1).length) {
						activeItem.removeClass('active');
						$('.suggestion-item').eq(activeItem.index() - 1).addClass('active');
					}
					e.stopImmediatePropagation();
					e.preventDefault();
					break;
				case 40: // key down
					var activeItem = $('.suggestion-item.active');
					if(activeItem.index() != -1) {
						if($('.suggestion-item').eq(activeItem.index() + 1).length) {
							activeItem.removeClass('active');
							$('.suggestion-item').eq(activeItem.index() + 1).addClass('active');
						}
						else {
							activeItem.removeClass('active');
							$('.suggestion-item').eq(0).addClass('active');
						}
					}
					else $('.suggestion-item').eq(0).addClass('active');
					e.stopImmediatePropagation();
					e.preventDefault();
					break;
				default:
					return;
			}
			});
		},
		
		// Функция выбора варианты из предложенных автокомплитом. Заполняется само поле и hidden-поле  
		selectItem : function(itemIndex) {
			var self = this;
			var item = self.lastAnswer[itemIndex];
			self.rightChoose = true;
			self.lastFieldValue = self.howSelect(item);
			self.autocompleteField.val(self.lastFieldValue);
			self.idEssenceField.val(item[self.essenceIdName]);
			self.autocompleteField.blur();
			if(self.onSelect) self.onSelect(item);
		},
		
		// Функция очистки поля при невыборе из предложенных вариантов
		clearField : function() {
			var self = this;
			self.autocompleteField.val(self.wrongString);
			self.idEssenceField.val('');
			self.lastFieldValue = '';
		},
		
		stopLookForField: function() {
			var self = this;
			self.isFocused = false;
			$('body').unbind('mousedown');
			self.autocompleteField.unbind('keyup blur');
			self.hideSuggestionList();
		},
		
		focusHeandler: function() {
			var self = this;
				self.autocompleteField.bind('focus', function() {
					if(!self.rightChoose) self.autocompleteField.val('');
					self.lookForField();
				});
		},
		
		request : function() {
			var self = this;
			$.ajax({
				url: W_AJAX + self.requestUrl,
				dataType: 'json',
				type: 'POST',
				data: {
					nameStartWith: self.autocompleteField.val()
				},
				success: function(data) {console.log(data);
					if(data.result = 'OK') {
						if(data.serverAnswer.length) {
							self.lastAnswer = data.serverAnswer;
							self.showSuggestionList();
						}
						else self.hideSuggestionList();
					}
				}
			});
		},
		
		makeupAnswer : function() {
			var self = this;
			var resultBlock = '';
			for(var i = 0; i < self.lastAnswer.length; i++) {
				resultBlock = resultBlock + '<div class="suggestion-item' + (i == 0 ? ' active' : '') + '">' + self.howShow(self.lastAnswer[i]) + '</div>';
			}
			return resultBlock;
		},
		
		hideSuggestionList : function() {
			$('.suggestion-list').hide().text('');
		},
		
		showSuggestionList : function() {
			var self = this;
			if(self.isFocused) $('.suggestion-list').html(self.makeupAnswer()).show();
		}
}